package com.spring.nio.service.chat.task;

import com.spring.nio.core.channel.pipeline.DefaultChannelPipeLine;
import com.spring.nio.core.event.model.PacketData;
import com.spring.nio.core.startup.BasicServer;
import com.spring.nio.util.LocalTime;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * 聊天消息执行读取处理单元
 * @author spring
 * */

@Slf4j
@SuppressWarnings("all")
public final class ChatReadEventTask implements Runnable {
    private PacketData packetData;

    public ChatReadEventTask(PacketData packetData) {
        this.packetData = packetData;
    }

    @Override
    public void run() {
        try {
            // 1、尝试加锁
            while (!BasicServer.chatLock.tryLock()) {
                try {
                    TimeUnit.MILLISECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatReadEventTask | --> success acquire lock, thread = {}", Thread.currentThread().getName());

            // 2、封装数据
            this.handler();
        } catch (Exception e) {
            // 结束执行单元
            log.error("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatReadEventTask | --> thread = {}, error = {}",
                Thread.currentThread().getName() , e.getMessage());
        } finally {
            BasicServer.chatLock.unlock();

            // 一旦某个帧处理失败，都会清空，否则会一直追加，导致内存泄露
            this.packetData.getSocketChannelContext().getRealList().clear();
            // 3、释放锁
            log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatReadEventTask | --> success release lock, thread = {}", Thread.currentThread().getName());
        }
    }

    private void handler() throws IOException {
        ((DefaultChannelPipeLine) this.packetData.getSocketChannelContext().getChannelPipeLine()).executeHandler(this.packetData);
    }
}
